
<!DOCTYPE html>
<html lang="zh-cn">
    
<head>
    <meta http-equiv="Content-Type" content="text/html" charset="UTF-8" >
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="generator" content="XGHeaven&#39;s Blog">
    <title>归档: 2017/6 - XGHeaven&#39;s Blog</title>
    <meta name="author" content="XGHeaven">
    
    
    
        <link rel="alternate" type="application/atom+xml" title="RSS" href="/atom.xml">
    
    <meta property="og:type" content="blog">
<meta property="og:title" content="XGHeaven&#39;s Blog">
<meta property="og:url" content="http://blog.xgheaven.cn/archives/2017/06/index.html">
<meta property="og:site_name" content="XGHeaven&#39;s Blog">
<meta property="og:locale" content="zh-cn">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="XGHeaven&#39;s Blog">
<meta name="twitter:creator" content="@XGHeaven">
    
    
        
    
    
        <meta property="og:image" content="https://www.gravatar.com/avatar/f34474afe04544ffbe944a804f0ae762?s=640"/>
    
    
    
    
    <!--STYLES-->
    <link rel="stylesheet" href="/assets/css/style-mhhgzztqkaub4zd4cl8bd83f7mgh9j6njnhilft4hamhrjsliqyzwo2cfzdk.min.css">
    <!--STYLES END-->
    
    <script type="text/javascript">
        var _gaq = _gaq || [];
        _gaq.push(['_setAccount', 'UA-71388235-1']);
        _gaq.push(['_trackPageview']);
        (function() {
            var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
            ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
            var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
        })();
    </script>

    
    <script type="text/javascript">
    var _hmt = _hmt || [];
    (function() {
      var hm = document.createElement("script");
      hm.src = "//hm.baidu.com/hm.js?9894361f828b64144ac1f2ac0c58c300";
      var s = document.getElementsByTagName("script")[0];
      s.parentNode.insertBefore(hm, s);
    })();
    </script>

</head>

    <body>
        <div id="blog">
            <!-- Define author's picture -->


    
        
    

<header id="header" data-behavior="1">
    <i id="btn-open-sidebar" class="fa fa-lg fa-bars"></i>
    <h1 class="header-title">
        <a class="header-title-link" href="/ ">XGHeaven&#39;s Blog</a>
    </h1>
    
        
            <a  class="header-right-picture "
                href="#about">
        
        
            <img class="header-picture" src="https://www.gravatar.com/avatar/f34474afe04544ffbe944a804f0ae762?s=90"/>
        
        </a>
    
</header>
            <!-- Define author's picture -->


    

<nav id="sidebar" data-behavior="1">
    
        <div class="sidebar-profile">
            <a href="/#about">
                    <img class="sidebar-profile-picture" src="https://www.gravatar.com/avatar/f34474afe04544ffbe944a804f0ae762?s=110"/>
            </a>
            <span class="sidebar-profile-name">XGHeaven</span>
        </div>
    
    
        <ul class="sidebar-buttons">
        
            <li class="sidebar-button">
                
                    <a  class="sidebar-button-link "
                         href="/ "
                        
                    >
                
                    <i class="sidebar-button-icon fa fa-lg fa-home"></i>
                    <span class="sidebar-button-desc">首页</span>
                </a>
        </li>
        
            <li class="sidebar-button">
                
                    <a  class="sidebar-button-link "
                         href="/all-categories"
                        
                    >
                
                    <i class="sidebar-button-icon fa fa-lg fa-bookmark"></i>
                    <span class="sidebar-button-desc">分类</span>
                </a>
        </li>
        
            <li class="sidebar-button">
                
                    <a  class="sidebar-button-link "
                         href="/all-tags"
                        
                    >
                
                    <i class="sidebar-button-icon fa fa-lg fa-tags"></i>
                    <span class="sidebar-button-desc">标签</span>
                </a>
        </li>
        
            <li class="sidebar-button">
                
                    <a  class="sidebar-button-link "
                         href="/all-archives"
                        
                    >
                
                    <i class="sidebar-button-icon fa fa-lg fa-archive"></i>
                    <span class="sidebar-button-desc">归档</span>
                </a>
        </li>
        
            <li class="sidebar-button">
                
                    <a  class="sidebar-button-link "
                         href="#about"
                        
                    >
                
                    <i class="sidebar-button-icon fa fa-lg fa-question"></i>
                    <span class="sidebar-button-desc">关于</span>
                </a>
        </li>
        
            <li class="sidebar-button">
                
                    <a  class="sidebar-button-link "
                         href="/friend-link"
                        
                    >
                
                    <i class="sidebar-button-icon fa fa-lg fa-link"></i>
                    <span class="sidebar-button-desc">友情链接</span>
                </a>
        </li>
        
    </ul>
    
        <ul class="sidebar-buttons">
        
            <li class="sidebar-button">
                
                    <a  class="sidebar-button-link " href="https://github.com/XGHeaven" target="_blank">
                
                    <i class="sidebar-button-icon fa fa-lg fa-github"></i>
                    <span class="sidebar-button-desc">GitHub</span>
                </a>
        </li>
        
            <li class="sidebar-button">
                
                    <a  class="sidebar-button-link " href="https://twitter.com/xgheaven" target="_blank">
                
                    <i class="sidebar-button-icon fa fa-lg fa-twitter"></i>
                    <span class="sidebar-button-desc">Twitter</span>
                </a>
        </li>
        
            <li class="sidebar-button">
                
                    <a  class="sidebar-button-link " href="https://facebook.com/xgheaven" target="_blank">
                
                    <i class="sidebar-button-icon fa fa-lg fa-facebook"></i>
                    <span class="sidebar-button-desc">Facebook</span>
                </a>
        </li>
        
            <li class="sidebar-button">
                
                    <a  class="sidebar-button-link " href="https://www.linkedin.com/xgheaven/" target="_blank">
                
                    <i class="sidebar-button-icon fa fa-lg fa-linkedin"></i>
                    <span class="sidebar-button-desc">LinkedIn</span>
                </a>
        </li>
        
            <li class="sidebar-button">
                
                    <a  class="sidebar-button-link " href="mailto:xgheaven@gmail.com" target="_blank">
                
                    <i class="sidebar-button-icon fa fa-lg fa-envelope-o"></i>
                    <span class="sidebar-button-desc">邮箱</span>
                </a>
        </li>
        
    </ul>
    
        <ul class="sidebar-buttons">
        
            <li class="sidebar-button">
                
                    <a  class="sidebar-button-link "
                         href="/atom.xml"
                        
                    >
                
                    <i class="sidebar-button-icon fa fa-lg fa-rss"></i>
                    <span class="sidebar-button-desc">RSS</span>
                </a>
        </li>
        
            <li class="sidebar-button">
                
                    <a  class="sidebar-button-link "
                         href="/changelog"
                        
                    >
                
                    <i class="sidebar-button-icon fa fa-lg fa-line-chart"></i>
                    <span class="sidebar-button-desc">Changelog</span>
                </a>
        </li>
        
    </ul>
    
</nav>

            
            <div id="main" data-behavior="1"
                 class="
                        hasCoverMetaIn
                        ">
                
    

<section class="postShorten-group main-content-wrap">
    
    
    <article class="postShorten postShorten--thumbnailimg-bottom" itemscope itemType="http://schema.org/BlogPosting">
        <div class="postShorten-wrap">
            <div class="postShorten-header">
                <h1 class="postShorten-title" itemprop="headline">
                    
                        <a class="link-unstyled" href="/2017/06/12/the-first-interview-of-alibaba-for-web-developer/">
                            阿里巴巴的前端实习生面试总结 - 其实是 Node.js
                        </a>
                    
                </h1>
                <div class="postShorten-meta">
    <time itemprop="datePublished" content="Mon Jun 12 2017 20:30:11 GMT+0800">
	
		    6月 12, 2017
    	
    </time>
    
        <span>发布在 </span>
        
    <a class="category-link" href="/categories/随笔/">随笔</a>


    
</div>
            </div>
            
            
                <div class="postShorten-content" itemprop="articleBody">
                    <p>17年4月，终于迎来了阿里巴巴的实习招聘，我也很开心的通过朴神内推到阿里云的前端开发。故事就是这么展开了。</p>
<p>还记得当初3月份（我也记不清了）朴神在微博上面发了谁愿意和他一起写 Node ，于是我激动的花了一晚上写了一张简历页面，开开心心的给了朴神，他给我回了一句：你联系方式都没有写，让我怎么联系你呀。QAQ，竟然忘了这么重要的事情，好丢脸。于是赶紧补了一下又给了朴神。</p>
<p>过了许久，等来了内推邮件，打开一看，哎不对啊，为啥是前端开发工程师？不是说好的写 Node 么-_-。于是又仔细看了阿里要的职位，发现原来 Node 是包含在前端开发工程师中的呀。</p>
<p style="color:white">也不知道是谁定的，Node竟然属于前端开发</p>

<p>不管了，于是又开开心心的填上去了。</p>
<p>Long Long Time Passed，果不其然，等来了第一次的电话面试。</p>
<p>电话面试简单来说他一开始先问了我一些关于 Node 方面的内容，比如对中间件的理解，平时遇到的一些困难，对模块化的运用等等，感觉自己都能答出来。之后他也问了一些前端的内容，我也说了一下之前也玩过手机浏览器内核，对兼容性稍微了解一些，<span style="color:white">用的时候查一下不就好了，何必要记住呢LOL</span>。</p>
<p>之后他说道自己是阿里云这边的，因为阿里云要面向海外市场，需要考虑手机兼容性的事情，问我愿意不愿意去解决兼容性的事情。于是我很老实的回答道：可以去做，但是能少碰到就碰到吧~~现在回想起来，我应该直接回答可以，不用加后面那句话。不过我确实想说一下自己的心声吧。</p>
<p>基本没有太多的卡壳，开开心心的结束了电话面试。原本以为自己说的比较好了，但是很久很久之后，都没有消息。某一天，朋友突然说道：“哎，你不用参加阿里的笔试么？”，我说道：“不用啊，我是内推的。”。说完之后我心里犯嘀咕，话说为啥这么久都没有消息，战战兢兢的打开了 campus.alibaba.com，点击个人中心……</p>
<img src="/2017/06/12/the-first-interview-of-alibaba-for-web-developer/reject1.png" alt="reject1.png" title="">
<p>WHAT THE FUCK!!! 被回绝了，为啥连个短信都没有的。心中一万个 🐴 飞过。</p>
<p>不过好事就是，我自动从内推变成了自主投递了，至少还有一次新的机会，这也就是说明今晚我要和他们一起笔试了~~都不明白自己是怎么被回绝的，连个原因都不写的么 😫 不管了，平复一下自己的心情，开始写笔试吧，就算不是内推，自主投递也可以的么。</p>
<p>几天后，笔试开始，前面的选择题就不多说了，没什么太难的，都是一些概念性的问题，包括 js 和 前端的。</p>
<blockquote>
<p>// 其实是我忘记有哪些选择题了</p>
</blockquote>
<p>主要说一些有一道算法题，就是让你将二进制转成十进制，大家第一个想到的便是 <code>Number.parseInt</code>，当然我也是的。不过想想也知道，肯定不会这么简单，坑的地方在于这个二进制很大，js 在处理超过 52 位二进制数的时候就会有精度问题，但是我的时间不多了，也懒得去写高精度了，要同时去写乘法和加法。不给当时时间太紧，其实是有更好的方法的。</p>
<p>简单来说，其实就是高精度的变种，只不过我们不需要实现乘法和加法。具体我就不讲了。</p>
<p>后面还要一道 canvas 的题目，让你画一个东西，反正我以前玩过，看着以前的代码，很快就撸出来了。</p>
<p>最后一道是简答题，让你说一下在实现自动保存功能的时候会遇到什么问题，多人合作会出现什么问题？WTF，这是什么问题啊。还好平时用过 quip 这种基于行锁的多人文本编辑工具，反正就大体扯了扯，顺便扯了一下如何优化前端的速度，和减轻服务器的负载。</p>
<p>于是，笔试结束了。感觉稍微有点虚，不过还是稍微有点信心的。也算是平复了一下内推被拒的心情吧。</p>
<p>依旧是漫长的等待，转眼已经5月中旬多了。这个时候还没有消息，我感觉都要跪了，都要打算去找别的公司了，因为再不找的话，就要错过找实习的最佳时机了。各大公司基本都是这个时候开始找实习的。（一些小公司的暑期实习除外）</p>
<p>就在我打算放弃的时候，就收到了阿里的远程一面的通知，这个时候挺开心的，于是就开开心心的去准备面试的内容了，也没心思去找别的公司了。</p>
<p>之后远程的一面、二面、hr面，不知不觉就到了6月份了。</p>
<p>一面的时候，面试官还是我们旁边的学校，我是杭电的，他是理工的。他问了一些问题，主要是关于 Node 的。这次真的是一点前端的内容都没有问。终于问了一下 Node 的内存管理机制，不过话说回来，和 java 的有点像，但不完全一样。记得 java 是采用引用计数的方式，node 是标记清除。不过 java 还有很多别的算法。聊了聊平时项目中遇到的问题，聊了聊 redis 的使用中遇到的坑。不过因为我用的太少，基本没什么坑可以踩。顺便问了我一个问题，就是说如果发现一个服务器的压力过大，该怎么处理（原句忘了，不过大体是这个意思）。想了一会，想到应该大体从代码和架构方面下手，一个优化代码，一个布置集群。但是不知道他想问我那个，于是半天没说。结果他说到，其实很简单的，就是将服务拆分，分布在不同的机器上就可以了。想了一下，嗯他说的也对。不知不觉，面试结束了。最后他说了一句，感觉你基础还可以，就是实践有点少，不过我先帮你送到后面去吧。其实他有一句话挺实在的，就是想要在后端有发展，最好要去学学 Java。但是我就是想在 node 混，除非我觉得 node 已经实现不了公司的需求的时候，我再尝试转 java。</p>
<p>就这样，一面结束了，感觉自己好水，其实很多问题都不能准确清楚的答出来。毕竟自己平时只是做项目的时候用了一下，而且项目不大，不会遇到太多性能问题，也就没有太多深入研究（其实是没那么多时间去研究，而且可以玩的技术还有那么多，想去玩新技术，于是就懒得太深入研究了）</p>
<p>过了许久，也不知道几天，反正感觉挺漫长的，终于等来了终面。</p>
<blockquote>
<p>阿里定义的终面有点歧义，不知道是实习生的终面还是技术的终面，不管了，既来之则安之。其实终面对于我来说就是技术二面和hr面LOL</p>
</blockquote>
<p>二面，问的问题更加具体了一些，没有问太基础的东西。主要是针对我平时项目中遇到的一些问题展开问了一下。感觉比一面问的少，但是聊的还挺开心的。讲了讲平时 docker 分发部署代码的东东。讲了讲为啥想来阿里，是为了技术还是朴神、deadhorse 他们的，我说都有😂。感觉这一面，他更多的是按照我的简历来提问的，反正也是瞎比回答么~~</p>
<p>然后就结束了，我原本以为这样就结束了，过几天再等 hr 面试。然后我就去搞我自己的 minecraft 管理器了。</p>
<p>结果突然间收到一个短信，说我被 hr 翻牌了，赶紧去准备面试。</p>
<p>OMG，这么快的，我都没准备呢。算了，兵来将挡，水来土掩，硬着头皮就上了，反正是 hr 面，不太需要将技术什么的，聊聊天就好了。我也不喜欢在别人面前装，反正我想说啥就说啥吧，没必要为了 hr 而特意去说他喜欢听的话。不过稍微说的好听点，我还是可以的。😂聊了聊阿里的武侠文化，花名文化，倒立文化等等。聊了聊平时的爱好，喜欢做啥。大学当中的收获什么的。说起这个，感觉大学收获最大的就是大一的时候和一些大神们出去瞎混，参加各种活动，d2，day one，coding线下会，黑客马拉松。coding 线下会拿到了一个洋葱猴顺便还认识了现在的 cnode 站长 alsotang，不过那个时候他还是在阿里工作A_A。而且自己不善于交际，打字聊天还可以，张口说话就不知道该说啥了，所以那个时候他也不认识我。不过听 alsotang 和 wph95 聊得挺开心的，才知道钉钉在阿里其实是蛮流行的，不过钉钉没有 gcm ，差评。</p>
<p>不过不得不佩服 wph95 大神，codevs站长。也就是因为他，我知道了 Angular，Docker，Webpack，Stylus，Gulp 等等好玩的东西。虽然他是做 python 后端的，但是他的知识面真的广，前端后端运维都有涉猎。看他和各位同行大佬撕逼的感觉真爽，尤其知道当他们知道他还是一个杭电学生的时候，哈哈哈，想想就好玩。而且大二上就去 Daocloud 实习了~~真的佩服他是怎么认识那么多人的😂。反正大二之后就不怎么和他联系了，挺感激他的</p>
<p>hr 面也就这么结束了，面试我的 hr 有点胖，顺便调侃了一下他能不能倒立，哈哈哈。</p>
<p>反正这几场面试下来，比较自信但是又没有把握。于是我就在纠结，这个时候已经快6月份了，要不要再去看看别的公司，于是发现那些内推的消息或者实习生的消息，基本都是2、3个月以前的了。饿了么，美团似乎连实习生招聘的链接都没有。腾讯估计已经结束了。自己觉得赌一把吧，到时候再说。</p>
<p>于是这一赌，就等来了下面的这个消息。而且依旧没有短信，我也是前几天耐不住性子了，去刷新了一下。你知道从面试中的状态变成已回绝的状态有多绝望么😫</p>
<img src="/2017/06/12/the-first-interview-of-alibaba-for-web-developer/reject2.png" alt="reject2.png" title="">
<p>这个时候，我开始找各大公司的实习，心累中。。。你早回绝一下也行，非要等到这么晚才回绝，而且还没有通知。</p>
<p>总结一下吧，就是面试笔试没什么太大难度，最后就被 K.O. 了。感觉就跟哑巴吃黄连，有苦说不出。。。真心不知道自己哪里 gg 了。也许是最后跟 hr 聊天的时候说我自己太懒吧，经常容易拖。经常是立下 flag 说今晚写完 api，然后晚上去玩 hadoop 了🐭。突然想起来 google 的 instant app 什么时候才能普及呢，好喜欢这个，感觉 react native 可以下岗了。</p>
<p>或许有的人说，你应该早就多准备，多投几个公司。说实话，我不是没有想过，投很多公司，假如正好只有一个公司要我，那还好。就算是一个都不要都可以。最怕的就是同时好几个公司要，如何拒绝其他公司，感觉这好为难啊（PS：这并不表明自己有多么自信，只是讲述一种可能）</p>
<p>最后说一句，感觉自己和大神有一个很大的差距便是大神总会有各种各样的获取信息的途径，而我，只能听大神说🐶而且他们感觉有时候就是一个代码机器，维护着好几个库，还能天天 push。</p>

                    
                        

                    
                    
                        <p>
                            <a href="/2017/06/12/the-first-interview-of-alibaba-for-web-developer/#post-footer" class="postShorten-excerpt_link link">
                                注释和共享
                            </a>
                        </p>
                    
                </div>
            
        </div>
        
    </article>
    
    
    <article class="postShorten postShorten--thumbnailimg-bottom" itemscope itemType="http://schema.org/BlogPosting">
        <div class="postShorten-wrap">
            <div class="postShorten-header">
                <h1 class="postShorten-title" itemprop="headline">
                    
                        <a class="link-unstyled" href="/2017/06/09/all-in-one-timer/">
                            All in One - Timer
                        </a>
                    
                </h1>
                <div class="postShorten-meta">
    <time itemprop="datePublished" content="Fri Jun 09 2017 00:50:14 GMT+0800">
	
		    6月 09, 2017
    	
    </time>
    
        <span>发布在 </span>
        
    <a class="category-link" href="/categories/All-in-One/">All in One</a>


    
</div>
            </div>
            
            
                <div class="postShorten-content" itemprop="articleBody">
                    <h1 id="All-in-one-Timer-定时器"><a href="#All-in-one-Timer-定时器" class="headerlink" title="All in one - Timer 定时器"></a>All in one - Timer 定时器</h1><h1 id="table-of-contents">目录</h1><ol class="toc"><li class="toc-item toc-level-1"><a class="toc-link" href="#All-in-one-Timer-定时器"><span class="toc-text">All in one - Timer 定时器</span></a></li><li class="toc-item toc-level-1"><a class="toc-link" href="#Golang"><span class="toc-text">Golang</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#Timer"><span class="toc-text">Timer</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#Ticker"><span class="toc-text">Ticker</span></a></li></ol></li></ol>
<p>这一篇文章，我们主要讲解一下不同语言之间关于定时器的操作和坑。</p>
<p>首先说一些这个坑中的一些前提，首先我这里所有的都是和 JavaScript 与 C++ 相比较进行学习的，所以下面不会出现 JavaScript 相关的教程，除非 JavaScript 在这个上面的坑太多，非讲不可。如果你没有相关的语言基础，请去学习。谢谢。</p>
<p>首先先从 golang 语言讲起来</p>
<h1 id="Golang"><a href="#Golang" class="headerlink" title="Golang"></a>Golang</h1><p>在 golang 中单次定时器和循环定时器分别是 Timer 和 Ticker。这两个都是一个结构体，结构如下</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">type</span> Timer <span class="keyword">struct</span> &#123;</div><div class="line">        C &lt;-<span class="keyword">chan</span> Time</div><div class="line">        <span class="comment">// contains filtered or unexported fields</span></div><div class="line">&#125;</div><div class="line"><span class="keyword">type</span> Ticker <span class="keyword">struct</span> &#123;</div><div class="line">        C &lt;-<span class="keyword">chan</span> Time <span class="comment">// The channel on which the ticks are delivered.</span></div><div class="line">        <span class="comment">// contains filtered or unexported fields</span></div><div class="line">&#125;</div></pre></td></tr></table></figure>
<p>其中 <code>C</code> 是一个 只读的 Time 类型的 channel，定时器根据传入的时间设置，定时向这个 channel 输入时间。你需要做的是等待这个 channel 中的数据。</p>
<p>每一个结构体都有如下方法：</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line"><span class="function"><span class="keyword">func</span> <span class="params">(t *Timer)</span> <span class="title">Reset</span><span class="params">(d Duration)</span> <span class="title">bool</span></span></div><div class="line"><span class="function"><span class="title">func</span> <span class="params">(t *Timer)</span> <span class="title">Stop</span><span class="params">()</span> <span class="title">bool</span></span></div><div class="line"><span class="function"><span class="title">func</span> <span class="params">(t *Ticker)</span> <span class="title">Stop</span><span class="params">()</span></span></div></pre></td></tr></table></figure>
<p>首先 Timer 和 Ticker 的区别不是很大，下面我们将两者的共性以 Timer 来讲述， 后面会针对两者不同的内容进行讲解。</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">package</span> main</div><div class="line"></div><div class="line"><span class="keyword">import</span> <span class="string">"time"</span></div><div class="line"></div><div class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span> &#123;</div><div class="line">    timer := time.NewTimer(time.Second * <span class="number">2</span>)</div><div class="line">  	time := &lt;- timer.C</div><div class="line">    <span class="built_in">println</span>(<span class="string">"Timer expired"</span>)</div><div class="line">&#125;</div></pre></td></tr></table></figure>
<p>参数接受一个时间参数，表示多久后向 channel 传输数据，也就是你想要定时的间隔，上面这个例子表示两秒之后输出 <code>Timer expired</code> 。</p>
<p>那么每次我们都要这么麻烦的设置一个时间，然后等待 channel，运行制定的函数么？</p>
<p>其实不是的，golfing 给我们内置了一个函数，类似于 JavaScript 的 setTimeout，那就是 AfterFunc。</p>
<p>函数如下：</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line"><span class="function"><span class="keyword">func</span> <span class="title">AfterFunc</span><span class="params">(d Duration, f <span class="keyword">func</span>()</span>) *<span class="title">Timer</span></span></div></pre></td></tr></table></figure>
<p>就是他会给你返回一个 <code>*Timer</code> ，并在指定时间之后，在 goroutine 中运行你的函数。</p>
<p>上面说完了如何启动，那么怎么停止呢？很简单，就是 <code>Stop</code>。</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">package</span> main</div><div class="line"></div><div class="line"><span class="keyword">import</span> <span class="string">"time"</span></div><div class="line"></div><div class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span> &#123;</div><div class="line">    timer := time.NewTimer(time.Second)</div><div class="line">    <span class="keyword">go</span> <span class="function"><span class="keyword">func</span><span class="params">()</span></span> &#123;</div><div class="line">        &lt;- timer.C</div><div class="line">        <span class="built_in">println</span>(<span class="string">"Timer expired"</span>)</div><div class="line">    &#125;()</div><div class="line">    stop := timer.Stop()</div><div class="line">    <span class="built_in">println</span>(<span class="string">"Timer cancelled:"</span>, stop)</div><div class="line">&#125;</div></pre></td></tr></table></figure>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">Timer cancelled: true</div></pre></td></tr></table></figure>
<p>调用停止之后，会返回一个 Bool 值：</p>
<ul>
<li><code>true</code> 停止成功</li>
<li><code>false</code> 已经被停止或者已经到期触发</li>
</ul>
<p>这里有一点需要注意的是，调用停止之后，并不会关闭 channel，如果你想检测那么你可以通过额外添加一个 done channel 来协助。</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">package</span> main</div><div class="line"></div><div class="line"><span class="keyword">import</span> <span class="string">"time"</span></div><div class="line"></div><div class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span> &#123;</div><div class="line">    timer := time.NewTimer(time.Second)</div><div class="line">    done := <span class="built_in">make</span>(<span class="keyword">chan</span> <span class="keyword">bool</span>)</div><div class="line">    <span class="keyword">go</span> <span class="function"><span class="keyword">func</span><span class="params">()</span></span> &#123;</div><div class="line">      <span class="keyword">select</span>&#123;</div><div class="line">        <span class="keyword">case</span> &lt;- timer.C:</div><div class="line">          <span class="built_in">println</span>(<span class="string">"Timer expired"</span>)</div><div class="line">        <span class="keyword">case</span> &lt;- done:</div><div class="line">          <span class="built_in">println</span>(<span class="string">"Timer stop"</span>)</div><div class="line">      &#125;</div><div class="line">    &#125;()</div><div class="line">    stop := timer.Stop()</div><div class="line">    done &lt;- <span class="literal">true</span></div><div class="line">    <span class="built_in">println</span>(<span class="string">"Timer cancelled:"</span>, stop)</div><div class="line">&#125;</div></pre></td></tr></table></figure>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line">Timer stop</div><div class="line">Timer cancelled: true</div></pre></td></tr></table></figure>
<p>所以比较麻烦，大家可以自己封装一下。</p>
<h2 id="Timer"><a href="#Timer" class="headerlink" title="Timer"></a>Timer</h2><p>单次定时器有一个特殊的方法就是 Reset，他可以将一个定时器的超时时间重新定义，这样你可以重复利用这个定时器。</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">package</span> main</div><div class="line"></div><div class="line"><span class="keyword">import</span> <span class="string">"time"</span></div><div class="line"></div><div class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span> &#123;</div><div class="line">    timer := time.NewTimer(time.Second)</div><div class="line">    <span class="keyword">go</span> <span class="function"><span class="keyword">func</span><span class="params">()</span></span> &#123;</div><div class="line">      &lt;- timer.C</div><div class="line">      <span class="built_in">println</span>(<span class="string">"Timer expired"</span>)</div><div class="line">      &lt;- timer.C</div><div class="line">      <span class="built_in">println</span>(<span class="string">"Timer expired again"</span>)</div><div class="line">    &#125;()</div><div class="line">    time.Sleep(time.Second * <span class="number">2</span>)</div><div class="line">    timer.Reset(time.Second)</div><div class="line">    time.Sleep(time.Second * <span class="number">2</span>)</div><div class="line">&#125;</div></pre></td></tr></table></figure>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line">Timer expired</div><div class="line">Timer expired again</div></pre></td></tr></table></figure>
<p>同理，你可以用在 AfterFunc 中</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">package</span> main</div><div class="line"></div><div class="line"><span class="keyword">import</span> <span class="string">"time"</span></div><div class="line"></div><div class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span> &#123;</div><div class="line">    timer := time.AfterFunc(time.Second, <span class="function"><span class="keyword">func</span><span class="params">()</span></span> &#123;</div><div class="line">      <span class="built_in">println</span>(<span class="string">"Timer expired"</span>)</div><div class="line">    &#125;)</div><div class="line">    time.Sleep(time.Second * <span class="number">2</span>)</div><div class="line">    timer.Reset(time.Second)</div><div class="line">    time.Sleep(time.Second * <span class="number">2</span>)</div><div class="line">&#125;</div></pre></td></tr></table></figure>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line">Timer expired</div><div class="line">Timer expired</div></pre></td></tr></table></figure>
<p>简直和 JavaScript 中的 setTimeout 像的不能再像了。</p>
<h2 id="Ticker"><a href="#Ticker" class="headerlink" title="Ticker"></a>Ticker</h2><p>这里的 Ticker 其实相当于 JavaScript 中的 setInterval，不过他没有类似 Timer 的 AfterFunc，只有一个最基础的构造器。</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">package</span> main</div><div class="line"></div><div class="line"><span class="keyword">import</span> <span class="string">"time"</span></div><div class="line"><span class="keyword">import</span> <span class="string">"fmt"</span></div><div class="line"></div><div class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span> &#123;</div><div class="line">    ticker := time.NewTicker(time.Millisecond * <span class="number">500</span>)</div><div class="line">    <span class="keyword">go</span> <span class="function"><span class="keyword">func</span><span class="params">()</span></span> &#123;</div><div class="line">        <span class="keyword">for</span> t := <span class="keyword">range</span> ticker.C &#123;</div><div class="line">            fmt.Println(<span class="string">"Tick at"</span>, t)</div><div class="line">        &#125;</div><div class="line">    &#125;()</div><div class="line">    time.Sleep(time.Millisecond * <span class="number">1500</span>)</div><div class="line">    ticker.Stop()</div><div class="line">    fmt.Println(<span class="string">"Ticker stopped"</span>)</div><div class="line">&#125;</div></pre></td></tr></table></figure>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div></pre></td><td class="code"><pre><div class="line">Tick at 2012-09-22 15:58:40.912926 -0400 EDT</div><div class="line">Tick at 2012-09-22 15:58:41.413892 -0400 EDT</div><div class="line">Tick at 2012-09-22 15:58:41.913888 -0400 EDT</div><div class="line">Ticker stopped</div></pre></td></tr></table></figure>
<p>Ticker 同样也有同 Timer 一样无法关闭 channel 的问题，解决方法和 Timer 类似，我就不多说了。</p>
<p>不过 Ticker 的 Stop 函数与 Timer 的不太一样，因为他没有是否触发过的问题，所以 Ticker 的 Stop是没有返回值的，这一点需要注意。</p>
<p>暂时先写这一个，以后如果有新的，持续更新。</p>

                    
                        

                    
                    
                        <p>
                            <a href="/2017/06/09/all-in-one-timer/#post-footer" class="postShorten-excerpt_link link">
                                注释和共享
                            </a>
                        </p>
                    
                </div>
            
        </div>
        
    </article>
    
    <div class="pagination-bar">
    <ul class="pagination">
        
        
        <li class="pagination-number">第 1 页 共 1 页</li>
    </ul>
</div>

</section>



                <footer id="footer" class="main-content-wrap">
    <span class="copyrights">
        Copyrights &copy; 2018 XGHeaven. All Rights Reserved.
    </span>
</footer>

            </div>
            
        </div>
        


    

<div id="about">
    <div id="about-card">
        <div id="about-btn-close">
            <i class="fa fa-remove"></i>
        </div>
        
            <img id="about-card-picture" src="https://www.gravatar.com/avatar/f34474afe04544ffbe944a804f0ae762?s=110"/>
        
            <h4 id="about-card-name">XGHeaven</h4>
        
            <h5 id="about-card-bio"><p>一个弱弱的码农</p>
</h5>
        
        
            <h5 id="about-card-job">
                <i class="fa fa-briefcase"></i>
                <br/>
                <p>杭州电子科技大学学生一枚</p>

            </h5>
        
        
            <h5 id="about-card-location">
                <i class="fa fa-map-marker"></i>
                <br/>
                Weifang Shandong, China
            </h5>
        
    </div>
</div>

        
<div id="cover" style="background-image:url('/static/images/20170217-TombRaider.jpg');"></div>
    </body>
    <!--SCRIPTS-->
<script src="/assets/js/scrip-z6xcdnzggiy56kzp83ux5nnbwra1acrauxruz3kdi3u5xladb6jh4n3ylebm.min.js"></script>
<!--SCRIPTS END-->



</html>
